<!--
 * @Descripttion: 侧边栏导航组件
 * @version: V1.0.0.1
 * @Author: zhaozhenzhuo
 * @Date: 2025-11-03 16:56:32
 * @LastEditors: zhaozhenzhuo
 * @LastEditTime: 2025-11-03 16:56:32
-->
<template>
	<div class="aside-bar-wrapper" id="asideBar">
		<el-popover
			v-for="item in list"
			:key="item.id"
			:content="item.name"
			placement="left"
			effect="dark"
		>
			<template #reference>
				<div
					class="bar-item"
					:class="{ active: activeId === item?.id }"
					@click="onClickItemHandle(item.id)"
				></div>
			</template>
		</el-popover>
	</div>
</template>

<script setup lang="ts">
import { ref, nextTick, watch, onMounted, onUnmounted } from 'vue';
import type { AsideListItemType, AsideHeightListItemType } from './AsideBar.type';

const props = withDefaults(
	defineProps<{
		list: AsideListItemType[];
		heightList: AsideHeightListItemType[];
		scrollContainerName: string;
	}>(),
	{
		list: () => [],
		heightList: () => [],
		scrollContainerName: ''
	}
);

// 高亮id
const activeId = ref<number | null>(null);

watch(
	() => props.heightList,
	(val) => {
		if (val?.length) {
			nextTick(() => {
				setActive();
			});
		}
	},
	{ immediate: true }
);

onMounted(() => {
	// 监听滚动
	monitorScroll();
});

onUnmounted(() => {
	// 取消监听滚动
	removeMonitorScroll();
});

// 设置高亮
const setActive = () => {
	// 获得当前的滚轮高度
	const scrollTop = document.querySelector(`.${props.scrollContainerName}`)?.scrollTop || 0;

	if (props.heightList && props.heightList.length) {
		for (let i = 0; i < props.heightList.length; i++) {
			// 如果滚轮高度大于当前所在的子元素高度 并且 滚轮高度小于下一个子元素的高度 ，那么说明滚轮在当前内容中，就激活当前的nav栏
			if (
				scrollTop >= props.heightList[i].height &&
				(!props.heightList[i + 1] || scrollTop <= props.heightList[i + 1]?.height)
			) {
				// 那么就激活当前的nav栏
				activeId.value = props.heightList[i].id;
			} else if (scrollTop <= props.heightList[0].height) {
				activeId.value = props.heightList[0].id;
			}
		}
	}
};

// 点击某项
const onClickItemHandle = (id: number) => {
	activeId.value = id;
	nextTick(() => {
		// 设置滚动条位置前先取消监听滚动事件
		removeMonitorScroll();
		// 滚动条滚到相应的模块
		const _heightObj = props.heightList.find((item) => item.id === id);
		const scrollContainerRef: HTMLElement | null = document.querySelector(
			`.${props.scrollContainerName}`
		);
		if (_heightObj && scrollContainerRef) {
			scrollContainerRef.scrollTop = _heightObj.height;
		}
		setTimeout(() => {
			// 设置后再恢复滚动条监听事件
			monitorScroll();
		}, 200);
	});
};

// 监听滚动条滚动
const monitorScroll = () => {
	const reportContentRef: HTMLElement | null = document.querySelector(
		`.${props.scrollContainerName}`
	);
	if (reportContentRef) {
		// 设置前先取消监听，防止重复设置
		reportContentRef.removeEventListener('scroll', setActive, true);
		reportContentRef.addEventListener('scroll', setActive, true);
	}
};

// 取消监听滚动条滚动
const removeMonitorScroll = () => {
	const reportContentRef: HTMLElement | null = document.querySelector(
		`.${props.scrollContainerName}`
	);
	if (reportContentRef) {
		reportContentRef.removeEventListener('scroll', setActive, true);
	}
};
</script>

<style lang="scss" scoped>
.aside-bar-wrapper {
	display: flex;
	flex-direction: column;
	gap: 0.6rem;
	position: absolute;
	right: 0.8rem;
	top: 50%;
	transform: translateY(-50%);

	.bar-item {
		position: relative;
		width: 1.5rem;
		height: 1.5rem;
		background: rgba($color: $bg-block-color-dark, $alpha: 0.1);
		border-radius: 50%;
		border: 1px solid #ffffff;
		cursor: pointer;

		&.active {
			background: $color-brand;
			border: 1px solid #ffffff;
		}
	}
}
</style>
<style>
.el-popover.el-popper {
	width: fit-content !important;
	min-width: fit-content !important;
	white-space: nowrap;
}
</style>
